package ui;

import index.Document;

import javax.swing.JFrame;

import java.awt.Desktop;
import java.awt.Font;
import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JMenuBar;
import javax.swing.JMenu;

import java.awt.event.ItemEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;

import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JTabbedPane;
import javax.swing.JScrollPane;
import javax.swing.BorderFactory;
import javax.swing.UIManager;
import javax.swing.border.EtchedBorder;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.border.TitledBorder;
import javax.swing.event.HyperlinkEvent;
import javax.swing.text.html.HTMLEditorKit;

import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JEditorPane;

import query.Querier;

import utils.Logger;
import utils.ThreadLock;
import utils.Util;

import java.awt.Cursor;
import javax.swing.ImageIcon;

public class Main extends JFrame
{
    private ThreadLock           lock                = null;
    private Main                 main                = null;
    private Map<Integer, String> urlMap              = null;
    private boolean              usePageRank         = false;
    private Querier              querier             = null;
    private JMenuBar             myMenuBar           = null;
    private JMenu                helpMenu            = null;
    private JMenu                fileMenu            = null;
    private JMenuItem            exitMenuItem        = null;
    private JTabbedPane          mainTabbedPane      = null;
    private JScrollPane          searchScrollPane    = null;
    private JScrollPane          crawlScrollPane     = null;
    private JPanel               searchPanel         = null;
    private JTextField           searchTextField     = null;
    private JButton              searchButton        = null;
    private JCheckBox            usePageRankCheckBox = null;
    private JLabel               jLabel              = null;
    private JPanel               jPanel              = null;
    private JEditorPane          resultEditorPane    = null;
    private JMenuItem            openMenuItem        = null;
    private JScrollPane          jScrollPane         = null;
    private JLabel               jLabel1             = null;
    private JMenuItem            aboutMenuItem       = null;

    /**
     * This method initializes
     * 
     */
    public Main()
    {
        super();
        try
        {
            UIManager.setLookAndFeel("com.nilo.plaf.nimrod.NimRODLookAndFeel");
        }
        catch (Exception e)
        {
            Logger.logException(e);
        }
        main = this;
        new Thread()
        {
            public void run()
            {
                new LoadingWindows(main);
            }
        }.start();
        try
        {
            Thread.sleep(1000);
        }
        catch (InterruptedException e)
        {
            Logger.logException(e);
        }
        getThreadLock().lock();
        getThreadLock().unlock();
        initialize();
    }

    /**
     * This method initializes this
     * 
     */
    private void initialize()
    {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //this.setContentPane(getMainTabbedPane());
        //this.setJMenuBar(getMyMenuBar());
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int x = (screenSize.width - 800) / 2;
        int y = (screenSize.height - 600) / 2;
        this.setSize(new Dimension(800, 600));
        this.setLocation(x, y);
        this.setJMenuBar(getMyMenuBar());
        this.setContentPane(getMainTabbedPane());
        this.setTitle("SearchEngineDemo");
        this.setResizable(false);
        this.setFont(new Font("\u65b0\u5b8b\u4f53", Font.PLAIN, 12));
        this.setVisible(true);
        this.getUrlMap();
        this.getQuerier();
    }

    /**
     * This method initializes myMenuBar
     * 
     * @return javax.swing.JMenuBar
     */
    private JMenuBar getMyMenuBar()
    {
        if (myMenuBar == null)
        {
            myMenuBar = new JMenuBar();
            myMenuBar.setFont(new Font("Dialog", Font.PLAIN, 12));
            myMenuBar.add(getFileMenu());
            myMenuBar.add(getHelpMenu());
        }
        return myMenuBar;
    }

    protected ThreadLock getThreadLock()
    {
        if (lock == null)
        {
            lock = new ThreadLock();
        }
        return lock;
    }

    protected Map<Integer, String> getUrlMap()
    {
        if (urlMap == null)
        {
            urlMap = Collections
                    .synchronizedMap(new HashMap<Integer, String>());
            try
            {
                File map = Util.getMapFile();
                InputStream in = new FileInputStream(map);
                byte[] b = new byte[in.available()];
                in.read(b);
                String[] contents = new String(b).split("\\s+");
                for (int i = 0; i < contents.length; i += 3)
                {
                    int key = Integer.parseInt(contents[i]);
                    String value = contents[i + 2];
                    urlMap.put(key, value);
                }
                in.close();
            }
            catch (Exception e)
            {
                Logger.logException(e);
            }
        }
        return urlMap;
    }

    /**
     * This method initializes helpMenu
     * 
     * @return javax.swing.JMenu
     */
    private JMenu getHelpMenu()
    {
        if (helpMenu == null)
        {
            helpMenu = new JMenu();
            helpMenu.setRolloverEnabled(true);
            helpMenu.setToolTipText("");
            helpMenu.setMnemonic(KeyEvent.VK_H);
            helpMenu.setFont(new Font("Dialog", Font.PLAIN, 12));
            helpMenu.setText("帮助(H)");
            helpMenu.add(getAboutMenuItem());
        }
        return helpMenu;
    }

    /**
     * This method initializes fileMenu
     * 
     * @return javax.swing.JMenu
     */
    private JMenu getFileMenu()
    {
        if (fileMenu == null)
        {
            fileMenu = new JMenu();
            fileMenu.setText("文件(F)");
            fileMenu.setFont(new Font("Dialog", Font.PLAIN, 12));
            fileMenu.setMnemonic(KeyEvent.VK_F);
            fileMenu.add(getOpenMenuItem());
            fileMenu.add(getExitMenuItem());
        }
        return fileMenu;
    }

    /**
     * This method initializes exitMenuItem
     * 
     * @return javax.swing.JMenuItem
     */
    private JMenuItem getExitMenuItem()
    {
        if (exitMenuItem == null)
        {
            exitMenuItem = new JMenuItem();
            exitMenuItem.setText("退出(E)");
            exitMenuItem.setFont(new Font("Dialog", Font.PLAIN, 12));
            exitMenuItem.setMnemonic(KeyEvent.VK_E);
            exitMenuItem.addActionListener(new java.awt.event.ActionListener()
            {
                public void actionPerformed(java.awt.event.ActionEvent e)
                {
                    System.exit(0);
                }
            });
        }
        return exitMenuItem;
    }

    /**
     * This method initializes querier
     * 
     * @return Querier
     */
    protected Querier getQuerier()
    {
        if (querier == null)
        {
            querier = new Querier();
        }
        return querier;
    }

    /**
     * This method initializes mainTabbedPane
     * 
     * @return javax.swing.JTabbedPane
     */
    private JTabbedPane getMainTabbedPane()
    {
        if (mainTabbedPane == null)
        {
            mainTabbedPane = new JTabbedPane();
            mainTabbedPane.setFont(new Font("Dialog", Font.PLAIN, 12));
            mainTabbedPane.setTabPlacement(JTabbedPane.BOTTOM);
            mainTabbedPane.addTab("搜索", null, getSearchScrollPane(), null);
        }
        return mainTabbedPane;
    }

    /**
     * This method initializes searchScrollPane
     * 
     * @return javax.swing.JScrollPane
     */
    private JScrollPane getSearchScrollPane()
    {
        if (searchScrollPane == null)
        {
            searchScrollPane = new JScrollPane();
            searchScrollPane.setBorder(BorderFactory
                    .createEtchedBorder(EtchedBorder.RAISED));
            searchScrollPane.setViewportView(getSearchPanel());
        }
        return searchScrollPane;
    }

    /**
     * This method initializes crawlScrollPane
     * 
     * @return javax.swing.JScrollPane
     */
    @SuppressWarnings("unused")
    private JScrollPane getCrawlScrollPane()
    {
        if (crawlScrollPane == null)
        {
            crawlScrollPane = new JScrollPane();
            crawlScrollPane.setBorder(BorderFactory
                    .createEtchedBorder(EtchedBorder.RAISED));
        }
        return crawlScrollPane;
    }

    /**
     * This method initializes searchPanel
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getSearchPanel()
    {
        if (searchPanel == null)
        {
            jLabel1 = new JLabel();
            jLabel1.setBounds(new Rectangle(739, 18, 23, 24));
            jLabel1.setIcon(new ImageIcon(getClass().getResource(
                    "/img/icon.gif")));
            jLabel1.setText("");
            jLabel = new JLabel();
            jLabel.setFont(new Font("\u65b0\u5b8b\u4f53", Font.PLAIN, 14));
            jLabel.setBounds(new Rectangle(39, 17, 100, 32));
            jLabel.setText("使用PageRank");
            searchPanel = new JPanel();
            searchPanel.setLayout(null);
            searchPanel.add(getSearchTextField(), null);
            searchPanel.add(getSearchButton(), null);
            searchPanel.add(getJPanel(), null);
            searchPanel.add(getJScrollPane(), null);
            searchPanel.add(jLabel1, null);
        }
        return searchPanel;
    }

    /**
     * This method initializes searchTextField
     * 
     * @return javax.swing.JTextField
     */
    private JTextField getSearchTextField()
    {
        if (searchTextField == null)
        {
            searchTextField = new JTextField();
            searchTextField.setBounds(new Rectangle(16, 15, 450, 32));
            searchTextField.setFont(new Font("\u65b0\u5b8b\u4f53", Font.PLAIN,
                    14));
            searchTextField.addKeyListener(new KeyAdapter()
            {
                public void keyPressed(KeyEvent e)
                {
                    if (e.getKeyCode() == KeyEvent.VK_ENTER)
                    {
                        query();
                    }
                }
            });
        }
        return searchTextField;
    }

    /**
     * This method initializes searchButton
     * 
     * @return javax.swing.JButton
     */
    private JButton getSearchButton()
    {
        if (searchButton == null)
        {
            searchButton = new JButton();
            searchButton.setBounds(new Rectangle(480, 16, 75, 32));
            searchButton
                    .setFont(new Font("\u65b0\u5b8b\u4f53", Font.PLAIN, 14));
            searchButton.setText("搜索");
            searchButton.setCursor(new Cursor(Cursor.HAND_CURSOR));
            searchButton.addMouseListener(new MouseAdapter()
            {
                public void mouseClicked(java.awt.event.MouseEvent e)
                {
                    query();
                }
            });
        }
        return searchButton;
    }

    private void query()
    {
        String str = searchTextField.getText().trim();
        if (str == null || str.isEmpty())
            return;
        final Map<Document, Double> result = getQuerier().query(str,
                usePageRank);
        Document[] documents = result.keySet().toArray(new Document[0]);
        Arrays.sort(documents, new Comparator<Document>()
        {
            public int compare(Document o1, Document o2)
            {
                double w1 = result.get(o1);
                double w2 = result.get(o2);
                if (Math.abs(w1 / w2 - 1) < 1E-9)
                    return 0;
                if (w1 > w2)
                    return -1;
                return 1;
            }
        });
        StringBuilder buffer = new StringBuilder();
        buffer
                .append("" //
                        + "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\""
                        + " \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n"
                        + "<html xmlns=\"http://www.w3.org/1999/xhtml\" >\n"
                        + "<head>\n"
                        + "    <title>无标题页</title>\n"
                        + "</head>\n"
                        + "<body>\n"
                        + "    <table style=\"width:80%; \" align=\"center\">\n");
        if (documents.length == 0)
            buffer.append("<tr><td>没有找到任何结果</tr></td>");
        for (int i = 0; i < 20 && i < documents.length; i++)
        {
            buffer.append(documents[i].getDisplayHtmlContent(urlMap
                    .get(documents[i].getDocumentID()), str, result
                    .get(documents[i])));
        }
        buffer.append("    </table>\n" + "</body>\n" + "</html>\n");
        resultEditorPane.setText(buffer.toString());
        resultEditorPane.setCaretPosition(0);
    }

    /**
     * This method initializes usePageRankCheckBox
     * 
     * @return javax.swing.JCheckBox
     */
    private JCheckBox getUsePageRankCheckBox()
    {
        if (usePageRankCheckBox == null)
        {
            usePageRankCheckBox = new JCheckBox();
            usePageRankCheckBox.setText("");
            usePageRankCheckBox.setMnemonic(KeyEvent.VK_P);
            usePageRankCheckBox.setBounds(new Rectangle(15, 22, 21, 21));
            usePageRankCheckBox.setCursor(new Cursor(Cursor.HAND_CURSOR));
            usePageRankCheckBox
                    .addItemListener(new java.awt.event.ItemListener()
                    {
                        public void itemStateChanged(java.awt.event.ItemEvent e)
                        {
                            usePageRank = (e.getStateChange() == ItemEvent.SELECTED);
                        }
                    });
        }
        return usePageRankCheckBox;
    }

    /**
     * This method initializes jPanel
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getJPanel()
    {
        if (jPanel == null)
        {
            jPanel = new JPanel();
            jPanel.setLayout(null);
            jPanel.setBounds(new Rectangle(563, 4, 150, 55));
            jPanel.setFont(new Font("\u65b0\u5b8b\u4f53", Font.PLAIN, 14));
            jPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
                    .createLineBorder(new Color(246, 202, 41), 1),
                    "PageRank\u8bbe\u7f6e", TitledBorder.DEFAULT_JUSTIFICATION,
                    TitledBorder.DEFAULT_POSITION, new Font("Dialog",
                            Font.PLAIN, 12), new Color(51, 51, 51)));
            jPanel.add(getUsePageRankCheckBox(), null);
            jPanel.add(jLabel, null);
        }
        return jPanel;
    }

    /**
     * This method initializes resultEditorPane
     * 
     * @return javax.swing.JEditorPane
     */
    private JEditorPane getResultEditorPane()
    {
        if (resultEditorPane == null)
        {
            resultEditorPane = new JEditorPane();
            resultEditorPane.setEditorKit(new HTMLEditorKit());
            resultEditorPane.setEditable(false);
            resultEditorPane.setFont(new Font("宋体", Font.PLAIN, 12));
            resultEditorPane
                    .addHyperlinkListener(new javax.swing.event.HyperlinkListener()
                    {
                        private Cursor ori  = new Cursor(Cursor.DEFAULT_CURSOR);
                        private Cursor hand = new Cursor(Cursor.HAND_CURSOR);

                        public void hyperlinkUpdate(HyperlinkEvent e)
                        {
                            HyperlinkEvent.EventType t = e.getEventType();
                            if (t == HyperlinkEvent.EventType.ACTIVATED)
                            {
                                try
                                {
                                    Desktop.getDesktop().browse(
                                            e.getURL().toURI());
                                }
                                catch (Exception e1)
                                {
                                    Logger.logException(e1);
                                }
                            }
                            else if (t == HyperlinkEvent.EventType.ENTERED)
                            {
                                resultEditorPane.setCursor(hand);
                            }
                            else
                            {
                                resultEditorPane.setCursor(ori);
                            }
                        }
                    });
        }
        return resultEditorPane;
    }

    /**
     * This method initializes openMenuItem
     * 
     * @return javax.swing.JMenuItem
     */
    private JMenuItem getOpenMenuItem()
    {
        if (openMenuItem == null)
        {
            openMenuItem = new JMenuItem();
            openMenuItem.setText("打开缓存文件(O)");
            openMenuItem.setMnemonic(KeyEvent.VK_O);
            openMenuItem.setFont(new Font("Dialog", Font.PLAIN, 12));
            openMenuItem.addActionListener(new java.awt.event.ActionListener()
            {
                public void actionPerformed(java.awt.event.ActionEvent e)
                {
                    String str = JOptionPane.showInputDialog(null, "请输入文件号");
                    try
                    {
                        int i = Integer.parseInt(str);
                        Desktop.getDesktop().browse(new URI(urlMap.get(i)));
                    }
                    catch (Exception e2)
                    {}
                }
            });
        }
        return openMenuItem;
    }

    /**
     * This method initializes jScrollPane
     * 
     * @return javax.swing.JScrollPane
     */
    private JScrollPane getJScrollPane()
    {
        if (jScrollPane == null)
        {
            jScrollPane = new JScrollPane();
            jScrollPane.setBounds(new Rectangle(16, 61, 752, 433));
            jScrollPane.setViewportView(getResultEditorPane());
        }
        return jScrollPane;
    }

    /**
     * This method initializes aboutMenuItem
     * 
     * @return javax.swing.JMenuItem
     */
    private JMenuItem getAboutMenuItem()
    {
        if (aboutMenuItem == null)
        {
            aboutMenuItem = new JMenuItem();
            aboutMenuItem.setFont(new Font("Dialog", Font.PLAIN, 12));
            aboutMenuItem.setMnemonic(KeyEvent.VK_A);
            aboutMenuItem.setText("关于(A)");
            aboutMenuItem.addActionListener(new java.awt.event.ActionListener()
            {
                public void actionPerformed(java.awt.event.ActionEvent e)
                {
                    JOptionPane.showMessageDialog(null,
                            "       COPYRIGHT © THSS\n    ALL RIGHTS RESERVED",
                            "关于", JOptionPane.INFORMATION_MESSAGE);
                }
            });
        }
        return aboutMenuItem;
    }

    public static void main(String[] args)
    {
        new Main();
    }
} // @jve:decl-index=0:visual-constraint="9,9"
